package org.eclipse.moquette.spi;

import org.eclipse.moquette.proto.messages.AbstractMessage;
import org.eclipse.moquette.spi.impl.events.PublishEvent;

import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.List;

/**
 * Created by alex on 15-5-31.
 */
public interface IMessagesStore {


    public static class StoredMessage implements Serializable {

        final AbstractMessage.QOSType m_qos;
        final byte[] m_payload;
        final String m_topic;

        public StoredMessage(byte[] message, AbstractMessage.QOSType qos, String topic) {
            m_qos = qos;
            m_payload = message;
            m_topic = topic;
        }

        public AbstractMessage.QOSType getQos() {
            return m_qos;
        }

        public ByteBuffer getPayload() {
            return (ByteBuffer) ByteBuffer.allocate(m_payload.length).put(m_payload).flip();
        }

        public String getTopic() {
            return m_topic;
        }
    }

    /**
     * 初始化存储器
     */
    void initStore();

    /**
     * 存储消息
     * If the message is empty then the topic is cleaned, else it's stored.
     * @param topic
     * @param message
     * @param qos
     */
    void storeRetained(String topic, ByteBuffer message, AbstractMessage.QOSType qos);

    /**
     * 返回符合条件的 StoredMessage
     * @param condition
     * @return
     */
    Collection<StoredMessage> searchMatching(IMatchingCondition condition);

    void storePublishForFuture(PublishEvent ev);

    List<PublishEvent> listMessagesInSession(String clientID);

    void removeMessageInSession(String clientID, int packetID);

    void dropMessagesInSession(String clientID);

    void cleanInFlight(String clientID, int packetID);

    void addInFlight(PublishEvent evt, String clientID, int packetID);

    /**
     * 返回下一个可用的消息ID
     * @param clientID
     * @return
     */
    int nextPacketID(String clientID);

    void close();

    void persistQoS2Message(String publishKey, PublishEvent evt);

    void removeQoS2Message(String publishKey);

    PublishEvent retrieveQoS2Message(String publishKey);

    void cleanRetained(String topic);
}
